/**
 * Created by Administrator on 2017/1/16.
 */

var MJPlayer = require('../MJ/player').MJPlayer;
var MJ = require('../MJ/MJ');
var Const = require('./const');
var SubCode = require('../subCode');

exports.XZMJPlayer = MJPlayer.extend({
    _selectedHSZCards: [],

    init: function(uid, msg) {
        this._super(uid, msg);

        this._stat.roundFan = 0;            // 本轮番数

        this._stat.zmCount = 0;             // 自摸次数
        this._stat.dpCount = 0;             // 点炮次数
        this._stat.dhCount = 0;             // 点胡次数
        this._stat.anGangCount = 0;        // 暗杠次数
        this._stat.mingGangCount = 0;      // 明杠次数

        this._selectedHSZCards = [];
    },

    getSelectedHSZCards: function() {
        return this._selectedHSZCards;
    },

    selectHSZCards: function(cards) {
        if (this._selectedHSZCards.length > 0) {
            return SubCode.MJ_HSZ_CARDS_SELECTED;
        }

        var colors = {};
        var objCards = {};
        cards.forEach(function(card) {
            ExObject.addNumber(objCards, card, 1);
            ExObject.addNumber(colors, MJ.getColor(card), 1);
        });

        if (Object.keys(colors).length != 1) {
            return SubCode.MJ_HSZ_CARDS_ERROR;
        }

        var cardEnough = true;
        ExObject.eachKeyNum(objCards, function(card, num) {
            if (!card || this._handCards.getCardNum(card) < num) {
                cardEnough = false;
            }
        }.bind(this));

        if (!cardEnough) {
            return SubCode.MJ_HSZ_CARDS_ERROR;
        }

        this._selectedHSZCards = cards;
        return Code.SUCCESS;
    },

    exchangeHSZCards: function(cards) {
        var handCards = this._handCards;

        this._selectedHSZCards.forEach(function(card) {
            handCards.delCard(card);
        });

        handCards.init(cards);

        this.sendReplay("onHSZCardExchanged", {
            playerIndex: this.getIndex(),
            cards: cards
        });
    },

    //getInitHandCardPreCards: function() {
    //    var preCards = [];
    //
    //    var distance = this.getRoom().getIndexDistance(this.getIndex(), this.getRoom().getDealerIndex());
    //    if (distance == 0) {
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 1));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 1));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 5));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 5));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 6));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 6));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 7));
    //        preCards.push(MJ.getValue(MJ.Color.TONG, 7));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 3));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 3));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 4));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 6));
    //    }
    //
    //    return preCards;
    //},

    settlementGangScore: function() {
        var room = this.getRoom();

        var notHuCount = room.getMaxPlayer() - room.getHuPlayerCount();

        if (!this.isRoundTing() && (notHuCount > 1)) {
            return;
        }

        var HJZY = room.getOptionEx("HJZY");

        var maIndex = room.calcMaIndex();
        var dealer = room.getDealerPlayer();

        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            var player = this;

            if (gangInfo.transIndex) {
                if (HJZY == 1) {
                    player = room.getPlayerByIndex(gangInfo.transIndex);
                } else if (HJZY == 2) {
                    player = room.getPlayerByIndex(gangInfo.transIndex);
                    if (player) {
                        player.addRoundItemScores(Const.ScoreRule.GANG, 1);
                    }
                } else {
                    continue;
                }
            } else {
                if (gangInfo.overdue || gangInfo.unscored) {
                    continue;
                }
            }

            var score = Const.GangScore[gangInfo.gang] || 0;
            gangInfo.targets.forEach(function(targetIndex) {
                var targetPlayer = room.getPlayerByIndex(targetIndex);
                if (targetPlayer) {
                    player.addRoundGangScore(score);
                    targetPlayer.addRoundGangScore(-score);

                    if (maIndex == player.getIndex()) {
                        targetPlayer.addRoundGangScore(-score);
                        dealer.addRoundGangScore(score);
                    } else if (maIndex == targetPlayer.getIndex()) {
                        dealer.addRoundGangScore(-score);
                        player.addRoundGangScore(score);
                    }
                }
            });
        }
    },

    settlementPatternScore: function() {
        if (!this.isRoundHu()) {
            return;
        }

        var player = this;
        var room = this.getRoom();
        var dealer = room.getDealerPlayer();

        var maIndex = room.calcMaIndex();
        var zms = room.getOption("ZMS");
        var isZM = (this.getRoundResult() == MJ.Result.ZM);
        if (isZM && zms == 2) {
            this.addRoundItemScores(Const.ScoreRule.ZM, 1);
        }

        var basicFan = this._stat.roundPatternScore + ExObject.sumValue(this._stat.roundItemScores);
        var maxFan = room.getOption("FAN");
        this._stat.roundFan = Math.min(maxFan, basicFan);

        var score = Math.pow(2, this._stat.roundFan);
        if (isZM && zms == 1) {
            score += 1;
        }

        var transPlayer = null;
        if (this.existRoundScoreRule(Const.ScoreRule.GSH) && room.getOption("DGH") == 1) {
            var gangIndex = this._gangCards.length - 1;
            if (gangIndex >= 0) {
                var gangInfo = this._gangCards[gangIndex];
                if (gangInfo.gang == MJ.Gang.DIAN) {
                    transPlayer = room.getPlayerByIndex(gangInfo.from);
                }
            }
        }

        // 结算牌型及基础分
        if (transPlayer) {
            var playerNum = this._stat.roundTarget.length;
            var allScore = score*playerNum;
            transPlayer.addRoundScore(-allScore);
            player.addRoundScore(allScore);

            if (player.getIndex() == maIndex) {
                transPlayer.addRoundScore(-allScore);
                dealer.addRoundScore(allScore);
            } else if (transPlayer.getIndex() == maIndex) {
                dealer.addRoundScore(-allScore);
                player.addRoundScore(allScore);
            }
        } else {
            this._stat.roundTarget.forEach(function(playerIndex) {
                var target = room.getPlayerByIndex(playerIndex);
                if (target) {
                    target.addRoundScore(-score);
                    player.addRoundScore(score);

                    if (player.getIndex() == maIndex) {
                        dealer.addRoundScore(score);
                        target.addRoundScore(-score);
                    } else if (target.getIndex() == maIndex) {
                        dealer.addRoundScore(-score);
                        player.addRoundScore(score);
                    }
                }
            });
        }
    },

    settlementTingScore: function() {
        var player = this;
        var room = this.getRoom();

        if (player.isRoundTing()) {
            return;
        }

        var maxFan = room.getOption("FAN");

        room.enumPlayers(function(eIndex, ePlayer) {
            if ((player.getIndex() != eIndex) && ePlayer.isRoundTing() && !ePlayer.isRoundHu()) {
                var basicFan = Const.PatternScore[ePlayer.getRoundPattern()] || 0;
                basicFan += ExObject.sumValue(ePlayer._stat.roundItemScores);
                var score = Math.pow(2, Math.min(maxFan, basicFan));

                player.addRoundScore(-score);
                ePlayer.addRoundScore(score);
            }
        });
    },

    /**
     * 判断是否是小胡
     * @param huCard
     * @param result
     */
    isXH: function(huCard) {
        var room = this.getRoom();

        var cards = clone(this._handCards.getCards());
        ExObject.addNumber(cards, huCard, 1);

        var gangFan = this._calcGangFan(cards, huCard);
        if (gangFan > 0) {
            return false;
        }

        var cardCount = MJ.sumCardsNum(cards);
        if (cardCount <= 2) {
            return false;
        }

        if (room.getPublicCards().getRemainNum() == 0) {
            return false;
        }

        if (room.getOption("YTL") && cardCount >= 9) { // 判断一条龙
            if (this._checkYTL(cards)) {
                return false;
            }
        }

        if (room.getOption("JXW")) {
            if (this._checkJXW(cards, huCard)) {
                return false;
            }
        }

        return true;
    },

    /**
     * 判断胡牌规则
     */
    settlementRules: function() {
        var room = this.getRoom();
        var player = this;

        if (!this.isRoundHu()) {
            return;
        }

        var huCard = this.getRoundHuCard();
        var cards = this.getRoundHuCards();
        var pattern = this.getRoundPattern();

        // 七对不计算杠番
        if (pattern != Const.Pattern.PAIR7 &&
            pattern != Const.Pattern.PAIR7_LONG &&
            pattern != Const.Pattern.PAIR7_COLOR &&
            pattern != Const.Pattern.PAIR7_COLOR_LONG &&
            pattern != Const.Pattern.JiangDui7) {
            var gangFan = this._calcGangFan(cards, huCard);
            if (gangFan > 0) {
                this.addRoundItemScores(Const.ScoreRule.GANG, gangFan);
            }
        }

        var cardCount = MJ.sumCardsNum(cards);
        if (cardCount <= 2) {
            var rule = Const.ScoreRule.SINGLE;
            this.setRoundScoreRule(rule);
            this.addRoundItemScores(rule, Const.ItemScore[rule]);
        }

        if (room.getPublicCards().getRemainNum() == 0) {
            if (this.getRoundResult() == MJ.Result.DH) {
                var rule = Const.ScoreRule.HaiDiHu;
                this.setRoundScoreRule(rule);
                this.addRoundItemScores(rule, Const.ItemScore[rule]);
            } else {
                if (this.existRoundScoreRule(Const.ScoreRule.GSH)) {
                    this.unsetRoundScoreRule(Const.ScoreRule.GSH);
                    var rule = Const.ScoreRule.HaiDiHua;
                    this.setRoundScoreRule(rule);
                    this.addRoundItemScores(rule, Const.ItemScore[rule]);
                } else {
                    var rule = Const.ScoreRule.SaoDiHu;
                    this.setRoundScoreRule(rule);
                    this.addRoundItemScores(rule, Const.ItemScore[rule]);
                }
            }
        }

        if (room.getOption("YTL") && cardCount >= 9) { // 判断一条龙
            if (this._checkYTL(cards)) {
                var rule = Const.ScoreRule.YiTiaoLong;
                this.setRoundScoreRule(rule);
                this.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
        }

        if (room.getOption("JXW")) {
            if (this._checkJXW(cards, huCard)) {
                var rule = Const.ScoreRule.JiaXinWu;
                this.setRoundScoreRule(rule);
                this.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
        }
    },

    /**
     * 判断胡牌规则
     */
    settlementTingRules: function(pattern, huCard) {
        var room = this.getRoom();
        var player = this;
        var rules = {};

        var cards = clone(this.getHandCards());
        ExObject.addNumber(cards, huCard, 1);

        // 七对不计算杠番
        if (pattern != Const.Pattern.PAIR7 &&
            pattern != Const.Pattern.PAIR7_LONG &&
            pattern != Const.Pattern.PAIR7_COLOR &&
            pattern != Const.Pattern.PAIR7_COLOR_LONG &&
            pattern != Const.Pattern.JiangDui7) {
            var gangFan = this._calcGangFan(cards, huCard);
            if (gangFan > 0) {
                rules[Const.ScoreRule.GANG] = gangFan;
            }
        }

        var cardCount = MJ.sumCardsNum(cards);
        if (cardCount <= 2) {
            var rule = Const.ScoreRule.SINGLE;
            rules[rule] = Const.ItemScore[rule];
        }

        if (room.getOption("YTL") && cardCount >= 9) { // 判断一条龙
            if (this._checkYTL(cards)) {
                var rule = Const.ScoreRule.YiTiaoLong;
                rules[rule] = Const.ItemScore[rule];
            }
        }

        if (room.getOption("JXW")) {
            if (this._checkYTL(cards, huCard)) {
                var rule = Const.ScoreRule.JiaXinWu;
                rules[rule] = Const.ItemScore[rule];
            }
        }

        return rules;
    },

    /**
     * 判断一条龙
     * @private
     */
    _checkYTL: function(cards) {
        var isYTL = false;

        var colors = this.getRoom().getSubConfig().colors;
        colors.forEach(function(color) {
            if (this._checkColorYTL(color, MJ.getColorCards(cards, color))) {
                isYTL = true;
            }
        }.bind(this));

        return isYTL;
    },

    _checkColorYTL: function(color, colorCards) {
        if (ExObject.count(colorCards) != 9) {
            return false;
        }

        var isYTL = false;
        var colorMinCard = MJ.getValue(color, 1);
        var colorMaxCard = MJ.getValue(color, MJ.COLOR_CARD_NUM);
        var colorSplits = MJ.splitColorCards(colorMinCard, colorMaxCard, colorCards);
        colorSplits.forEach(function(items) {
            var itemCards = {};
            items.forEach(function(item) {
                if (item.length == 3) {
                    if (item[0] != item[1]) { //不是三张一样的牌
                        itemCards[item[0]] = 1;
                        itemCards[item[1]] = 1;
                        itemCards[item[2]] = 1;
                    }
                }
            });

            if (ExObject.count(itemCards) == 9) {
                isYTL = true;
            }
        });

        return isYTL;
    },

    /**
     * 判断夹心五
     * @param cards
     * @param huCard
     * @private
     */
    _checkJXW: function(cards, huCard) {
        var huPoint = MJ.getPoint(huCard);
        if (huPoint != 5) {
            return false;
        }

        var isJiaXinWu = false;
        var huColor = MJ.getColor(huCard);
        var huColorCards = MJ.getColorCards(cards, huColor);
        var huColorMinCard = MJ.getValue(huColor, 1);
        var huColorMaxCard = MJ.getValue(huColor, MJ.COLOR_CARD_NUM);

        var colorSplits = MJ.splitColorCards(huColorMinCard, huColorMaxCard, huColorCards);
        colorSplits.forEach(function(items) {
            items.forEach(function(item) {
                if (isJiaXinWu) {
                    return;
                }

                if (item.length == 2) {
                    if (item[0] == huCard) {
                        isJiaXinWu = true;
                    }
                } else if (item.length == 3) {
                    if (item[0] != item[1]) { //不是三张一样的牌
                        if (huCard == item[1]) { //夹张
                            isJiaXinWu = true;
                        }
                    }
                }
            });
        });

        return isJiaXinWu;
    },

    setTingRules: function(rules) {
        if (!rules) {
            return;
        }

        var player = this;
        ExObject.eachKeyNum(rules, function(rule, value) {
            player.setRoundScoreRule(rule);
            player.addRoundItemScores(rule, value);
        });
    },

    _calcGangFan: function(cards, huCard) {
        var gangFan = this._gangCards.length;

        this._pengCards.forEach(function(card) {
            if (cards[card]) {
                gangFan++;
            }
        });

        gangFan += ExObject.countEQ(cards, 4);

        return gangFan;
    },

    transLastGangTo: function(targetIndex) {
        var gangIndex = this._gangCards.length - 1;
        if (gangIndex < 0) {
            return;
        }

        var gangInfo = this._gangCards[gangIndex];
        gangInfo.transIndex = targetIndex;
    },

    settlement: function() {
        this._super();

        this.addRoundScore(this._stat.roundGangScore);

        if (this._stat.roundResult == MJ.Result.ZM) {
            this._stat.zmCount++;
        } else if (this._stat.roundResult == MJ.Result.DH) {
            this._stat.dhCount++;
            if (this._stat.roundTarget.length > 0) {
                var dpPlayer = this.getRoom().getPlayerByIndex(this._stat.roundTarget[0]);
                if (dpPlayer) {
                    dpPlayer._stat.dpCount++;
                }
            }
        }

        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                this._stat.anGangCount++;
            } else {
                this._stat.mingGangCount++;
            }
        }
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getReconnectInfo: function(isSelf) {
        var info = this._super(isSelf);
        info.selectedHSZCards = this._selectedHSZCards;
        if (!isSelf) {
            info.selectedHSZCards = clone(this._selectedHSZCards);
            for (var i = 0, l = info.selectedHSZCards.length; i < l; ++i) {
                info.selectedHSZCards[i] = 1;
            }
        }

        return info;
    },

    getSettlementInfo: function() {
        var info = this._super();
        info.gangCards = this._gangCards;
        info.pengCards = this._pengCards;
        info.handCards = this._handCards.getCards();
        return info;
    },

    onStartNewRound: function() {
        this._super();
        this._selectedHSZCards = [];
        this._stat.roundFan = 0;
    },

    //getInitHandCardPreCards: function() {
    //    var preCards = [];
    //
    //    var distance = this.getRoom().getIndexDistance(this.getIndex(), this.getRoom().getDealerIndex());
    //    if (distance == 0) {
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 1));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 1));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 2));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 3));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 7));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 7));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 7));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 8));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 8));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 8));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //        preCards.push(MJ.getValue(MJ.Color.TIAO, 9));
    //    } else if (distance == 1) {
    //
    //    } else {
    //
    //    }
    //
    //    return preCards;
    //},

    checkHuLogic: function(cards, huCard) {
        var pattern = this._super(cards, huCard);
        if (pattern == MJ.Pattern.NONE) {
            return pattern;
        }

        if (pattern == MJ.Pattern.SINGLE) {
            pattern = MJ.Pattern.PAIR;
        }

        var colors = this.getColorsWithCards(cards);

        var exPattern = 0;
        if (colors.length == 1) { // 清一色
            exPattern = 5;
        }

        if (pattern == MJ.Pattern.PAIR7) {
            if (ExObject.countEQ(cards, 4) > 0) {
                exPattern += 2;
            }
        }

        if (exPattern) {
            pattern = pattern*10 + exPattern;
        }

        var room = this.getRoom();

        if (room.getOption("YJJD")) {
            if (pattern == Const.Pattern.NORMAL || pattern == Const.Pattern.NORMAL_COLOR) {
                var hu19 = true;
                colors.forEach(function (color) {
                    var colorHu19 = false;
                    var splitResults = MJ.splitColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), MJ.getColorCards(cards, color));
                    splitResults.forEach(function (result) {
                        var is19 = true;
                        result.forEach(function (item) {
                            var point = MJ.getPoint(item[0]);
                            if (item.length == 2) {
                                if (point != 1 && point != 9) {
                                    is19 = false;
                                }
                            } else if (item.length == 3) {
                                if (item[0] == item[1]) {
                                    if (point != 1 && point != 9) {
                                        is19 = false;
                                    }
                                } else {
                                    if (point != 1 && point != 7 && point != 9) {
                                        is19 = false;
                                    }
                                }
                            }
                        })

                        if (is19) {
                            colorHu19 = true;
                        }
                    });

                    if (!colorHu19) {
                        hu19 = false;
                    }
                });

                if (hu19) {
                    pattern = Const.Pattern.DaiYaoJiu;
                }
            }

            if (pattern == Const.Pattern.PAIR || pattern == Const.Pattern.PAIR7 || pattern == Const.Pattern.PAIR7_LONG) { //判断 将对
                var isJiangDui = true;

                this._pengCards.forEach(function(card) {
                    var point = MJ.getPoint(card);
                    if (point != 2 && point != 5 && point != 8) {
                        isJiangDui = false;
                    }
                });

                this._gangCards.forEach(function(gangInfo) {
                    var point = MJ.getPoint(gangInfo.card);
                    if (point != 2 && point != 5 && point != 8) {
                        isJiangDui = false;
                    }
                });

                if (isJiangDui) {
                    ExObject.eachKeyNum(cards, function(card, num) {
                        var point = MJ.getPoint(card);
                        if (point != 2 && point != 5 && point != 8) {
                            isJiangDui = false; return false;
                        }
                    });
                }

                if (isJiangDui) {
                    if (pattern == Const.Pattern.PAIR) {
                        pattern = Const.Pattern.JiangDui;
                    } else if (pattern == Const.Pattern.PAIR7 || pattern == Const.Pattern.PAIR7_LONG) {
                        pattern = Const.Pattern.JiangDui7;
                    }
                }
            }
        }

        if (room.getOption("MQZZ")) { //门清中张
            if (pattern == Const.Pattern.NORMAL) {
                var isMenQing = true;
                if (this._pengCards.length != 0) {
                    isMenQing = false;
                }

                this._gangCards.forEach(function (gangInfo) {
                    if (gangInfo.gang == MJ.Gang.BA || gangInfo.gang == MJ.Gang.DIAN) {
                        isMenQing = false;
                    }
                });

                if (isMenQing) {
                    pattern = Const.Pattern.MenQing;
                }
            }

            if (pattern == Const.Pattern.NORMAL) {
                var isZZ = true;
                this._pengCards.forEach(function(card) {
                    var point = MJ.getPoint(card);
                    if (point == 1 || point == 9) {
                        isZZ = false;
                    }
                });

                this._gangCards.forEach(function(gangInfo) {
                    var point = MJ.getPoint(gangInfo.card);
                    if (point == 1 || point == 9) {
                        isZZ = false;
                    }
                });

                ExObject.each(cards, function(card, num) {
                    var point = MJ.getPoint(card);
                    if (point == 1 || point == 9) {
                        isZZ = false;
                    }
                });

                if (isZZ) {
                    pattern = Const.Pattern.ZhongZhang;
                }
            }
        }

        return pattern;
    },
});